package com.hjm.project.settleInfo.settleInfo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hjm.common.exception.BusinessException;
import com.hjm.common.utils.DateUtils;
import com.hjm.common.utils.LogUtils;
import com.hjm.common.utils.StringUtils;
import com.hjm.common.utils.poi.ExcelUtil;
import com.hjm.common.utils.security.ShiroUtils;
import com.hjm.framework.aspectj.lang.annotation.Log;
import com.hjm.framework.aspectj.lang.enums.BusinessType;
import com.hjm.framework.web.controller.BaseController;
import com.hjm.framework.web.domain.AjaxResult;
import com.hjm.framework.web.page.TableDataInfo;
import com.hjm.project.bankInfo.bankInfo.domain.QbBankInfo;
import com.hjm.project.bankInfo.bankInfo.service.IQbBankInfoService;
import com.hjm.project.merPaid.merPaid.domain.MerPaid;
import com.hjm.project.merPaid.merPaid.domain.MerPaidVo;
import com.hjm.project.merPaid.merPaid.service.IMerPaidService;
import com.hjm.project.settleInfo.settleInfo.service.ISettleInfoService;
import com.hjm.project.walletDetails.walletDetails.domain.WalletDetails;
import com.hjm.project.walletDetails.walletDetails.service.IWalletDetailsService;
import com.yxhd.encrypt.EncryptUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

/**
 * 清结算Controller
 *
 * @author LOVE
 * @date 2020-11-23
 */
@Controller
@RequestMapping("/settleInfo/settleInfo")
public class SettleInfoController extends BaseController
{
    private String prefix = "settleInfo/settleInfo";

    @Resource
    private ISettleInfoService settleInfoService;

    @Resource
    private IMerPaidService merPaidService;

    @Resource
    private IQbBankInfoService bankInfoService; //支行总行表
    @Resource
    private IWalletDetailsService walletDetailsService;


    @RequiresPermissions("settleInfo:settleInfo:unPayList")
    @GetMapping("/unPayList")
    public String unPayList()
    {
        return prefix + "/unPayList";
    }

    /**
     * 未出款数据列表
     */
    @RequiresPermissions("settleInfo:settleInfo:unPayList")
    @PostMapping("/unPayList")
    @ResponseBody
    public TableDataInfo unPayList(@RequestParam Map<String,Object> params) throws Exception
    {
        startPage();
        //查询未出款的数据
        params.put("settle_state","0");
        List<Map<String,Object>> list = settleInfoService.unPayList(params);
        return getDataTable(list);
    }

    @RequiresPermissions("settleInfo:settleInfo:examlist")
    @GetMapping("/examlist")
    public String examlist()
    {
        return prefix + "/examlist";
    }
    /**
     * 审核单
     */
    @RequiresPermissions("settleInfo:settleInfo:examlist")
    @PostMapping("/examlist")
    @ResponseBody
    public TableDataInfo examlist(@RequestParam Map<String,Object> params)
    {
        startPage();
        List<Map<String,Object>> list = settleInfoService.getOrderPageList(params);
        return getDataTable(list);
    }

    /**
     * 出款失败数据
     * @return
     */
    @RequiresPermissions("settleInfo:settleInfo:errorPayList")
    @GetMapping("/errorPayList")
    public String errorPayList()
    {
        return prefix + "/errorPayList";
    }

    /**
     * 出款失败数据
     */
    @RequiresPermissions("settleInfo:settleInfo:errorPayList")
    @PostMapping("/errorPayList")
    @ResponseBody
    public TableDataInfo errorPayList(@RequestParam Map<String,Object> params) throws Exception
    {
        startPage();
        //0-未出款数据菜单、1-所有出款数据、2-出款失败
        params.put("settle_state","-2");
        //传入排序字段
        params.put("sort", "tmoney desc");
        List<Map<String,Object>> list =  settleInfoService.unPayList(params);
        return getDataTable(list);
    }

    /**
     * 查看交易未清算的数据（交易成功但是没清算，补录数据）
     * @return
     */
    @RequiresPermissions("settleInfo:settleInfo:jqDate")
    @GetMapping("/jqDate")
    public String jqDate()
    {
        return prefix + "/jqDate";
    }
    /**
     * 查看交易未清算的数据（交易成功但是没清算，补录数据）
     */
    @RequiresPermissions("settleInfo:settleInfo:jqDate")
    @PostMapping("/jqDate")
    @ResponseBody
    public TableDataInfo jqDate(@RequestParam Map<String,Object> params)
    {
        startPage();
        params.put("au_state0", 0);
        params.put("au_state1", -3);
        params.put("msgtype", "H007");
        params.put("msgtype1", "L007");
        List<Map<String,Object>> list= new ArrayList<>();
        if (params.get("type") == null || "1".equals(params.get("type"))) {
            //线下交易
           list=settleInfoService.showNoqingsuan(params);
        } else if ("2".equals(params.get("type"))) {
            //线上交易
            list=settleInfoService.showNoqingsuanOnline(params);
        }
        return getDataTable(list);
    }
    /**
     * 查看交易未清算的数据（交易成功但是没清算，补录数据）
     * @return
     */
    @RequiresPermissions("settleInfo:settleInfo:ckData")
    @GetMapping("/ckData")
    public String ckData()
    {
        return prefix + "/ckData";
    }
    /**
     * 清算未出款（清算数据有没有出款数据）
     *
     * @param params
     * @return
     * @throws Exception
     */
    @RequiresPermissions("settleInfo:settleInfo:ckData")
    @PostMapping("/ckData")
    @ResponseBody
    public TableDataInfo ckData(@RequestParam Map<String,Object> params)
    {
        List<Map<String,Object>> list=settleInfoService.showNoChukuan(params);
        return getDataTable(list);
    }


    /**
     * 清结算管理 商户出款冻结查询
     * @return
     */
    @RequiresPermissions("settleInfo:settleInfo:forzenPayList")
    @GetMapping("/forzenPayList")
    public String forzenPayList()
    {
        return prefix + "/forzenPayList";
    }
    /**
     * 清结算管理 商户出款冻结查询
     *
     * @param params
     * @return
     * @throws Exception
     */
    @RequiresPermissions("settleInfo:settleInfo:forzenPayList")
    @PostMapping("/forzenPayList")
    @ResponseBody
    public TableDataInfo forzenPayList(@RequestParam Map<String,Object> params) throws Exception
    {
        params.put("balances_status", "-3");
        List<Map<String,Object>> list=settleInfoService.getUnpayTranddelList(params);
        return getDataTable(list);
    }


    /**
     * 扣款数据
     * @return
     */
    @RequiresPermissions("settleInfo:settleInfo:deductList")
    @GetMapping("/deductList")
    public String deductList()
    {
        return prefix + "/deductList";
    }
    /**
     * 扣款数据
     *
     * @param params
     * @return
     * @throws Exception
     */
    @RequiresPermissions("settleInfo:settleInfo:deductList")
    @PostMapping("/deductList")
    @ResponseBody
    public TableDataInfo deductList(@RequestParam Map<String,Object> params)
    {
        List<Map<String,Object>> list=settleInfoService.getDeductPageList(params);
        return getDataTable(list);
    }

    @RequiresPermissions("settleInfo:settleInfo:payList")
    @GetMapping("/payList")
    public String payList()
    {
        return prefix + "/payList";
    }

    /**
     * 所有付款数据
     */
    @RequiresPermissions("settleInfo:settleInfo:payList")
    @PostMapping("/payList")
    @ResponseBody
    public TableDataInfo payList(@RequestParam Map<String,Object> params) throws Exception
    {
        startPage();
        //0-未出款数据菜单、1-所有出款数据
        params.put("searchType",1);
        //传入排序字段
        params.put("sort", "auditdate desc,tmoney desc");
        List<Map<String,Object>> list = settleInfoService.unPayList(params);
        return getDataTable(list);
    }

    @RequiresPermissions("settleInfo:settleInfo:hisList")
    @GetMapping("/hisList")
    public String hisListpayList()
    {
        return prefix + "/hisList";
    }

    /**
     * 历史打款单
     */
    @RequiresPermissions("settleInfo:settleInfo:merchantUnPay")
    @PostMapping("/hisList")
    @ResponseBody
    public TableDataInfo hisList(@RequestParam Map<String,Object> params)
    {
        startPage();
        params.put("state","1");
        List<Map<String,Object>> list = settleInfoService.getRemittanceBillsList(params);
        return getDataTable(list);
    }
    @RequiresPermissions("settleInfo:settleInfo:merchantUnPay")
    @GetMapping("/merchantUnPay")
    public String merchantUnPay()
    {
        return prefix + "/merchantUnPay";
    }

    /**
     * 商户未结款
     */
    @RequiresPermissions("settleInfo:settleInfo:merchantUnPay")
    @PostMapping("/merchantUnPay")
    @ResponseBody
    public TableDataInfo merchantUnPay(@RequestParam Map<String,Object> params)
    {
        startPage();
        List<Map<String,Object>> list = settleInfoService.getMerchantUnPay(params);
        return getDataTable(list);
    }
    @RequiresPermissions("settleInfo:settleInfo:payAbleList")
    @GetMapping("/payAbleList")
    public String payAbleList(ModelMap mmap)
    {
        mmap.put("mindDate", DateUtils.getDate());
        mmap.put("maxDate", DateUtils.getDate());
        return prefix + "/payAbleList";
    }

    /**
     * 应付数据
     */
    @RequiresPermissions("settleInfo:settleInfo:payAbleList")
    @PostMapping("/payAbleList")
    @ResponseBody
    public TableDataInfo payAbleList(@RequestParam Map<String,Object> params)
    {
        startPage();
        if (null==params.get("mindDate")){
            params.put("mindDate", DateUtils.getDate());
        }
        if (null==params.get("maxDate")){
            params.put("maxDate", DateUtils.getDate());
        }
        List<Map<String,Object>> list = settleInfoService.getPayAbleList(params);
        return getDataTable(list);
    }




    /**
     * 修改结算信息
     * @Param [merNo, mmap]
     * @Return java.lang.String
     */
    @GetMapping("/updateBank/{settleSerial}")
    @Log(title = "前往修改结算页面", businessType = BusinessType.UPDATE)
    public String updateBank(@PathVariable("settleSerial") String settleSerial, ModelMap mmap) throws Exception {
        //根据流水获取当前流水所对应的结算卡
        MerPaid merPaid1 = new MerPaid();
        merPaid1.setSettleSerial(settleSerial);
        List<MerPaid> merPaids = merPaidService.selectMerPaidList(merPaid1);
        if (CollectionUtils.isEmpty(merPaids)) {
            throw  new BusinessException("当前出款流水不存在");
        }

        MerPaid merPaid = merPaids.get(0);
        //总行信息
        QbBankInfo qbBankInfo = new QbBankInfo();
        qbBankInfo.setSubbranchName(merPaid.getBankName());
        List<QbBankInfo> qbBankInfos = bankInfoService.selectQbBankInfoList(qbBankInfo);
        if (CollectionUtils.isEmpty(qbBankInfos)) {
            throw  new BusinessException("银行卡信息错误");
        }
        String bankName = qbBankInfos.get(0).getBankName();
        mmap.put("settleSerial",settleSerial);          //出款流水
        mmap.put("bankHeadname",bankName);              //总行
        mmap.put("bankName",merPaid.getBankName());     //所属支行
        mmap.put("bankNum", merPaid.getBankNum());      //支行行号
        mmap.put("screenNum", EncryptUtils.getDecrypt(merPaid.getScreenNum()));   //结算卡号
        mmap.put("screenName",merPaid.getScreenName()); //结算人名
        mmap.put("id",merPaid.getId());                 //主键
        return prefix + "/updateBank";
    }


    /**
     * 修改出款记录结算信息
     */
    @RequiresPermissions("merPaid:merPaid:remove")
    @Log(title = "修改出款记录结算信息", businessType = BusinessType.UPDATE)
    @PostMapping( "/updateMerPaid")
    @ResponseBody
    public AjaxResult updateMerPaid(@RequestParam Map param) throws Exception {
        LogUtils.logInfo("开始修改出款账户");
        MerPaid merPaid = new MerPaid();
        merPaid.setBankName(String.valueOf(param.get("bankName")));
        merPaid.setBankNum(String.valueOf(param.get("bankNum")));
        merPaid.setId(Long.parseLong(String.valueOf(param.get("id"))));
        merPaid.setScreenName(String.valueOf(param.get("screenName")));
        merPaid.setScreenNum(EncryptUtils.getEncrypt(String.valueOf(param.get("screenNum"))).trim());
        int i = merPaidService.updateMerPaid(merPaid);
        //更新成功后增加备注
        if (i > 0) {
            MerPaid mer = new MerPaid();
            mer.setId(Long.parseLong(param.get("id").toString()));
            MerPaid merPaid1 = merPaidService.selectMerPaidList(mer).get(0);
            mer.setRemarks(merPaid1.getRemarks() + "【修改结算账户-" + DateUtils.getDateTime() + "】");
            int i1 = merPaidService.updateMerPaid(mer);
            if (i1 <= 0) {
                LogUtils.logInfo("修改出款账户备注失败");
            }
        }
        LogUtils.logInfo("修改出款账户结束:" + toAjax(i));
        return toAjax(i);
    }


    /**
     * 发起未知查询
     * @Param [param]
     * @Return com.hjm.framework.web.domain.AjaxResult
     */
    @RequiresPermissions("merPaid:merPaid:queryUnknown")
    @Log(title = "发起未知查询", businessType = BusinessType.UPDATE)
    @PostMapping( "/queryUnknown")
    @ResponseBody
    public AjaxResult queryUnknown() throws Exception {
        //获取所有未知数据
        MerPaid merPaid = new MerPaid();
        merPaid.setSettleState("0");
        merPaidService.queryUnknown(merPaid);
        return success("查询处理中,请稍后进行查询..............");
    }



    /**
     * 修改出款失败的数据状态 为 0-待处理 以便重新出款
     * @Param [param]
     * @Return com.hjm.framework.web.domain.AjaxResult
     */
    @RequiresPermissions("merPaid:merPaid:errorAgain")
    @Log(title = "失败重新出款(修改数据状态)", businessType = BusinessType.UPDATE)
    @PostMapping( "/errorAgain")
    @ResponseBody
    public AjaxResult errorAgain(@RequestParam Map params,String[] ids) throws Exception {
        if (params.get("ids") == null || ids.length == 0) {
            return error("请至少选择一条数据");
        }
        //获取所有未知数据
        MerPaid merPaid = new MerPaid();
        merPaid.setSettleState("-2");
        merPaid.setIds(ids);
        merPaidService.errorAgain(merPaid);
        return AjaxResult.success("出款数据处理中,请稍后前往未出款查看");
    }
    /**
     * 重新出款
     * @Param [param]
     * @Return com.hjm.framework.web.domain.AjaxResult
     */
    @RequiresPermissions("merPaid:merPaid:errorAgain")
    @Log(title = "重新出款", businessType = BusinessType.UPDATE)
    @PostMapping( "/reloadMoney")
    @ResponseBody
    public AjaxResult reloadMoney(@RequestParam Map params,String[] ids) throws Exception {
        //获取所有未知数据
        if (params.get("ids") == null || ids.length == 0) {
            return error("请至少选择一条数据");
        }
        MerPaid merPaid = new MerPaid();
        merPaid.setSettleState("0");
        merPaid.setIds(ids);
        return merPaidService.reloadMoney(merPaid);
    }


    /**
     * 商户重新出款
     * @Param [param]
     * @Return com.hjm.framework.web.domain.AjaxResult
     */
    @RequiresPermissions("merPaid:merPaid:errorAgain")
    @Log(title = "商户重新出款", businessType = BusinessType.UPDATE)
    @PostMapping( "/merReloadMoney")
    @ResponseBody
    public AjaxResult merReloadMoney(@RequestParam Map params,String[] ids) throws Exception {
        //获取所有未知数据
        if (params.get("ids") == null || ids.length == 0) {
            return error("请至少选择一条数据");
        }
        MerPaid merPaid = new MerPaid();
        merPaid.setSettleState("0");
        merPaid.setIds(ids);
        return merPaidService.merReloadMoney(merPaid);
    }


    /**
     * 交易未清算线下，直接请求计费接口
     * @return
     */
    @RequestMapping("saveQingsuan")
    @ResponseBody
    public AjaxResult saveQingsuan(String serials,String type){
        try {
            //提交计费程序
            Map<String,String> resultMap=settleInfoService.saveQingsuan(serials,type);
            return AjaxResult.success(resultMap.get("resultMsg"));
        } catch (Exception e) {
            return AjaxResult.success("交易未清算异常:" + e.getMessage());
        }
    }


    /**
     * 交易未清算线上，直接请求计费接口
     * @return
     */
    @RequestMapping("saveQingsuanOnline")
    @ResponseBody
    public AjaxResult saveQingsuanOnline(String serials,String type){
        try {
            //提交计费程序
            Map<String,String> resultMap=settleInfoService.saveQingsuanOnline(serials,type);
            return AjaxResult.success(resultMap.get("resultMsg"));
        } catch (Exception e) {
            return AjaxResult.success("交易未清算异常:" + e.getMessage());
        }
    }



    /**
     * 出款解冻
     * @return
     */
    @Log(title = "出款解冻", businessType = BusinessType.UPDATE)
    @RequestMapping("saveThawStatus")
    @ResponseBody
    public AjaxResult saveThawStatus(@RequestParam Map params){
        try {
            int result = settleInfoService.saveThawStatus(params);
            return toAjax(result);
        } catch (Exception e) {
            return AjaxResult.success("出款解冻异常:" + e.getMessage());
        }
    }


    /**
     * 代付对账查询
     * @return
     */
    @GetMapping("/tradeNoQs")
    public String tradeNoQs() {
        return prefix + "/tradeNoQs";
    }


    /**
     * 代付对账查询
     * @return
     */
    @PostMapping("/tradeNoQsList")
    @ResponseBody
    public TableDataInfo tradeNoQsList(@RequestParam Map<String,Object> params) throws Exception {
        params.put("start1",String.valueOf(params.get("start")).replaceAll("-",""));
        params.put("end1",String.valueOf(params.get("end")).replaceAll("-",""));
        startPage();
        List<Map<String,Object>> list = settleInfoService.tradeNoQsList(params);
        return getDataTable(list);
    }



    /**
     * 清结算管理,出款补录,补录通知
     * @Param [paramMap]
     * @Return java.util.Map
     */
    @Log(title = "补录通知", businessType = BusinessType.INSERT)
    @RequestMapping("saveBuLu")
    @ResponseBody
    public Map saveBuLu(@RequestParam Map<String,Object> params) throws Exception {
        try {
            Integer result= settleInfoService.saveBuLu(params);
            return toAjax(result);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


    /**
     * 出款解冻 -3 改为 待处理
     * @Param [paramMap]
     * @Return java.util.Map
     */
    @Log(title = "解冻通知", businessType = BusinessType.UPDATE)
    @RequestMapping("saveJieDong")
    @ResponseBody
    public Map saveJieDong(@RequestParam Map<String,Object> params) throws Exception {
        try {
            Integer result= settleInfoService.saveJieDong(params);
            return toAjax(result);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


    /**
     * 手动重新入账
     * @return
     */
    @Log(title = "重新入账", businessType = BusinessType.UPDATE)
    @RequestMapping("saveInputMoney")
    @ResponseBody
    public  AjaxResult saveInputMoney(@RequestParam Map params){
        //获取到流水号之后，根据流水号去查询信息
        try {
            String serials = String.valueOf(params.get("serials"));
            String type = String.valueOf(params.get("type"));
            //提交手动入账
            Map<String,String> resultMap = settleInfoService.saveInputMoney(serials,type);
            String result = resultMap.get("result");
            String resultMsg = resultMap.get("resultMsg");
            if ("0".equals(result)) {
                return success(resultMsg);
            }
            return error(resultMsg);
        } catch (Exception e) {
            e.printStackTrace();
            return error("提交入账处理异常");
        }
    }


    /**
     * 结算导出
     * @param params
     * @return
     * @throws Exception
     */
    @RequestMapping("/exportSettleInfo")
    @ResponseBody
    public AjaxResult exportSettleInfo(@RequestParam Map params) throws Exception {
        List<Map<String, Object>> merPaiList = settleInfoService.getMerPaiList(params);
        List<MerPaidVo> list = new ArrayList<>();
        for (Map<String, Object> data : merPaiList) {
            data.put("SCREEN_NUM", EncryptUtils.getDecrypt(data.get("SCREEN_NUM").toString()));
            String jsonString = JSONObject.toJSONString(data);
            MerPaidVo mp = JSON.parseObject(jsonString, MerPaidVo.class);
            list.add(mp);
        }
        ExcelUtil excelUtil = new ExcelUtil(MerPaidVo.class);
        return  excelUtil.exportExcel(list, "结算信息" + DateUtils.dateTimeNow());
    }


    @RequestMapping("importSettleInfo")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importSettleInfo(MultipartFile file) throws Exception {
        ExcelUtil<MerPaidVo> util = new ExcelUtil<MerPaidVo>(MerPaidVo.class);
        List<MerPaidVo> merPaids = util.importExcel(file.getInputStream());
        for (MerPaidVo merPaid : merPaids) {
            if (StringUtils.isBlank(merPaid.getUpdateStatus())) {
                return error("未设置回更状态," + merPaid.getSETTLE_SERIAL());
            }
            Map params = new HashMap();
            params.put("settle_serial",merPaid.getSETTLE_SERIAL());
            List<Map<String, Object>> merPaiList = settleInfoService.getMerPaiList(params);
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(merPaiList)) {
                return error("无效数据或数据不支持回更," + merPaid.getSETTLE_SERIAL());
            }
            String settleState = merPaiList.get(0).get("SETTLE_STATE").toString();
            if ("1".equals(settleState)) {
                return error("不可操作出款成功数据," + merPaid.getSETTLE_SERIAL());
            } else if ("-3".equals(settleState)) {
                return error("不可操作已冻结数据," + merPaid.getSETTLE_SERIAL());
            }

            List<String> statusList = Arrays.asList("1", "-2", "-3");

            if (!statusList.contains(merPaid.getUpdateStatus())) {
                return error("无效的回更状态," + merPaid.getSETTLE_SERIAL());
            }
            String note = ";" + ShiroUtils.getLoginName() + "于" + DateUtils.getDateTime() + "回更结算;回更的状态为:" + merPaid.getUpdateStatus() + ";";
            int i = settleInfoService.updateMerPaid(merPaid.getUpdateStatus(),note,merPaid.getSETTLE_SERIAL());
            if (i <= 0) {
                return error("更新失败" + merPaid.getSETTLE_SERIAL());
            }
            //回更提现
            WalletDetails wa = new WalletDetails();
            wa.setStatus("1");
            wa.setSerial(merPaid.getSETTLE_SERIAL());
            wa.setRemarks(ShiroUtils.getLoginName() + "-手动出款");
            walletDetailsService.updatewalletDetails(wa);

        }
        return success("操作成功");
    }


    @GetMapping("/importTemplate")
    @ResponseBody
    public AjaxResult importTemplate() {
        ExcelUtil<MerPaidVo> util = new ExcelUtil<>(MerPaidVo.class);
        return util.importTemplateExcel("结算信息" + DateUtils.dateTimeNow());
    }



    /**
     * 出款打回
     * @param params
     * @return
     * @throws Exception
     */
    @RequestMapping("/saveCkReject")
    @ResponseBody
    public AjaxResult saveCkReject(@RequestParam Map params) throws Exception {
        AjaxResult ajaxResult = settleInfoService.saveCkReject(params);
        return ajaxResult;
    }
}
